package com.rc.saas.tenant.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.rc.saas.tenant.interceptor.SpmInterceptor;
import com.rc.saas.tenant.interceptor.TenantOperateLogInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * 扩展springmvc功能
 * spring boot @ImportResource 拦截器不起作用 ???
 * SpringBoot2使用的Spring5，因此将WebMvcConfigurerAdapter改为WebMvcConfigurer
 * 使用WebMvcConfigurer扩展SpringMVC好处既保留了SpringBoot的自动配置，又能用到我们自己的配置
 * @EnableWebMvc 如果我们需要全面接管SpringBoot中的SpringMVC配置则开启此注解，开启后，SpringMVC的自动配置将会失效。
 * <p>
 * Created by sven on 2019/9/29
 */
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {
    /**
     * 将bean交给Spring容器实例化
     * @return
     */
    @Bean
    public TenantOperateLogInterceptor tenantOperateLogInterceptor() {
        return new TenantOperateLogInterceptor();
    }

    /**
     * 将bean交给Spring容器实例化
     * @return
     */
    @Bean
    public SpmInterceptor spmInterceptor() {
        return new SpmInterceptor();
    }

    //@Override
    //public void addViewControllers(ViewControllerRegistry registry) {
    //    registry.addViewController("/index.jsp").setViewName("index");
    //}

    //@Override
    //public void addViewControllers(ViewControllerRegistry registry) {
    //    registry.addViewController("/").setViewName("/webapp/index.html");
    //    registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    //}

    /**
     * 同时在配置拦截器时候，添加拦截器不能使用new AppInterceptor()，而是应该使用@Bean注册的方法，进行方法调用添加到拦截器配置里
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //<!-- 拦截所有的请求，这个必须写在前面，也就是写在【不拦截】的上面 -->
        //<!-- 匹配的是url路径， 如果不配置或/**,将拦截所有的Controller -->
        //<!--<mvc:mapping path="/**"/>-->
        //<!--<mvc:exclude-mapping path="/swagger-resources/**"/>-->
        //<!--<mvc:exclude-mapping path="/v2/**"/>-->
        //<!--<mvc:exclude-mapping path="/swagger-ui.html"/>-->
        //<!--<mvc:exclude-mapping path="/index"/>-->

        ///appjs/** = anon
        ///libjs/** = anon
        ///static/** = anon
        ///include/** = anon
        ///templates/** = anon
        ///locales/** = anon
        ///favicon.ico = anon

        registry.addInterceptor(spmInterceptor())
        //拦截项目中的哪些请求
        .addPathPatterns("/login", "/welcome", "/welcome2");

        registry.addInterceptor(tenantOperateLogInterceptor())
                //拦截项目中的哪些请求
                .addPathPatterns("/**")
                //对项目中的哪些请求不拦截
                //.excludePathPatterns("/appjs/**")
                //.excludePathPatterns("/libjs/**")
                //.excludePathPatterns("/static/**")
                //.excludePathPatterns("/include/**")
                //.excludePathPatterns("/templates/**")
                //.excludePathPatterns("/locales/**")
                //.excludePathPatterns("/captcha/**")
                //.excludePathPatterns("/welcome/**")
                //.excludePathPatterns("/welcome2/**")
                //.excludePathPatterns("/console/**")
                //.excludePathPatterns("/empty/**");

                .excludePathPatterns("/appjs/**",
                        "/libjs/**",
                        "/static/**",
                        "/include/**",
                        "/templates/**",
                        "/locales/**",
                        "/captcha/**",
                        "/welcome",
                        "/test/*",
                        "/welcome2",
                        "/printerRecord/printOrder",
                        "/printerRecord/airPrinter",
                        "/printerRecord/selectEpgnamePrirtuaById",
                        "/printerRecord/savePrintOrder",
                        "/printerRecord/selectEpgnamePrirtuaByName",
                        "/console",
                        "/empty");
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //调用父类的配置
        WebMvcConfigurer.super.configureMessageConverters(converters);
        //创建FastJson的消息转换器
        FastJsonHttpMessageConverter convert = new FastJsonHttpMessageConverter();
        //创建FastJson的配置对象
        FastJsonConfig config = new FastJsonConfig();
        //对Json数据进行格式化
        config.setSerializerFeatures(SerializerFeature.PrettyFormat,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteNullNumberAsZero,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullBooleanAsFalse,
                SerializerFeature.WriteMapNullValue,
                //禁止循环引用
                SerializerFeature.DisableCircularReferenceDetect);
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        config.setCharset(Charset.forName("UTF-8"));
        convert.setFastJsonConfig(config);
        convert.setSupportedMediaTypes(getSupportedMediaTypes());
        converters.add(convert);
    }

    public List<MediaType> getSupportedMediaTypes() {
        //创建fastJson消息转换器
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XML);
        supportedMediaTypes.add(MediaType.IMAGE_GIF);
        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
        supportedMediaTypes.add(MediaType.IMAGE_PNG);
        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        supportedMediaTypes.add(MediaType.TEXT_XML);
        supportedMediaTypes.add(MediaType.ALL);
        return supportedMediaTypes;
    }

    //extends WebMvcConfigurationSupport {
    //SpringBoot中自动配置了:
    //ViewResolver（视图解析器）
    //ContentNegotiatingViewResolver（组合所有的视图解析器）
    //自动配置了静态资源文件夹、静态首页、favicon.ico及Webjars
    //Converter（转换器，转换类型使用）
    //Formatter（格式化器）
    //HttpMessageConverter（对SpringMVC的请求和响应进行序列化）
    //MessageCodesResolver（定义错误代码生成规则）
    //ConfigurableWebBindingInitializer（Web数据绑定器）

}
